package com.uam.core.entity.uitls;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mapbox.geojson.Point;
import com.uam.core.entity.model.TaskModel;
import com.uam.core.entity.model.TrackPoint;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.locationtech.jts.geom.Coordinate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Administrator
 */
@Slf4j
public class CurrentListGroup {

    /**
     * 按照连续的数字分组
     *
     * @param numbers
     * @return
     */
    public static List<List<Integer>> groupConsecutiveNumbers(List<Integer> numbers) {
        List<List<Integer>> groups = new ArrayList<>();
        if (numbers.isEmpty()) {
            return groups;
        }
        // 先排序
        Collections.sort(numbers);
        List<Integer> currentGroup = new ArrayList<>();
        currentGroup.add(numbers.get(0));
        for (int i = 1; i < numbers.size(); i++) {
            int currentNumber = numbers.get(i);
            int previousNumber = numbers.get(i - 1);

            // 如果当前数字与前一个数字连续，则将其添加到当前分组中
            if (currentNumber - previousNumber == 1) {
                currentGroup.add(currentNumber);
            } else {
                // 否则，将当前分组添加到结果列表中，并创建一个新的分组
                groups.add(new ArrayList<>(currentGroup));
                currentGroup.clear();
                currentGroup.add(currentNumber);
            }
        }
        // 添加最后一个分组
        groups.add(new ArrayList<>(currentGroup));

        return groups;
    }

    public static boolean isInRectangle(JSONArray listPoint, String newRectgle) {
        String[] rectangleArray = newRectgle.split(";");
        String[] minArray = rectangleArray[0].split("\\,");
        String[] maxArray = rectangleArray[1].split("\\,");
        int row = listPoint.size();
        for (int i = 0; i < row; i++) {
            JSONArray indexKey = listPoint.getJSONObject(i).getJSONArray("position");
            double lat = indexKey.getDouble(0);
            double lng = indexKey.getDouble(1);;
            boolean flag = GeoUtil.isInRectangleArea(lat, lng, Double.valueOf(minArray[0]), Double.valueOf(maxArray[0]), Double.valueOf(minArray[1]), Double.valueOf(maxArray[1]));
            if (!flag) {
                return false;
            }
        }
        return true;
    }

    public static boolean isInRectangle(List<Integer> index,List<TrackPoint>  listPoint, String newRectgle) {
        String[] rectangleArray = newRectgle.split(";");
        String[] minArray = rectangleArray[0].split("\\,");
        String[] maxArray = rectangleArray[1].split("\\,");
        int row = index.size();
        for (int i = 0; i < row; i++) {
            TrackPoint indexKey = listPoint.get(index.get(i));
            double lat = indexKey.getPosition()[0];
            double lng =  indexKey.getPosition()[1];
            boolean flag = GeoUtil.isInRectangleArea(lat, lng, Double.valueOf(minArray[0]), Double.valueOf(maxArray[0]), Double.valueOf(minArray[1]), Double.valueOf(maxArray[1]));
            if (!flag) {
                return false;
            }
        }
        return true;
    }


    public static JSONArray isInRectangle(TaskModel task,List<TrackPoint> track) {
        if(StringUtils.isBlank(task.getAvoidancePoint())){
            return new JSONArray();
        }
        JSONArray jsonArray=JSONArray.parseArray(task.getAvoidancePoint());
        if(jsonArray == null || jsonArray.size() ==0){
            return new JSONArray();
        }

        //在区域内有冲突
        boolean flag = CurrentListGroup.isInRectangle(jsonArray, task.getRectanglePoint());
        if(flag){
            //取中间点
            JSONObject jsonObject=jsonArray.getJSONObject(1);
            String ownId=jsonObject.getString("id");

            int row=track.size();
            for(int i=0;i<row;i++){
                TrackPoint trackPoint=track.get(i);
                //是冲突点
                if (trackPoint.isConflictPoint() &&  trackPoint.getId().equals(ownId)) {
                        JSONArray strArr = getAddPoint(i - 2, i, track);
                        Collections.reverse(strArr);
                        jsonArray.addAll(0, strArr);
                        jsonArray.addAll(getAddPoint(i + 2, i + 3, track));
                  break;
                }
            }
            soutData(track,jsonArray);
            return jsonArray;
        }
        return new JSONArray();
    }

    public static void soutData(List<TrackPoint> track,JSONArray jsonArray){
        StringBuffer sbOld=new StringBuffer();
        track.forEach(a->{
            sbOld.append(a.getPosition()[0]);
            sbOld.append(",");
            sbOld.append(a.getPosition()[1]);
            sbOld.append(";");
        });
        sbOld.deleteCharAt(sbOld.length()-1);


        StringBuffer sb=new StringBuffer();
        for(int i=0;i<jsonArray.size();i++) {
            JSONObject a=jsonArray.getJSONObject(i);
            sb.append(a.getJSONArray("position").getDouble(0));
            sb.append(",");
            sb.append(a.getJSONArray("position").getDouble(1));
            sb.append(";");
        }

        sb.deleteCharAt(sb.length()-1);
        System.out.println("计算前--"+sb.toString());
        System.out.println("计算后--"+sbOld.toString());
        System.out.println("-------------------------");
    }

    public static JSONArray getAddPoint(int startIndex,int endIndex,List<TrackPoint> track){
        JSONArray jsonArrayStart=new JSONArray(16);
        try {
            List<TrackPoint> trackStart = track.subList(startIndex, endIndex);
            trackStart.forEach(a -> {
                JSONObject jsonObjectStart = new JSONObject();
                jsonObjectStart.put("id", a.getId());
                JSONArray jsnTemp = new JSONArray();
                jsnTemp.add(a.getPosition()[0]);
                jsnTemp.add(a.getPosition()[1]);
                jsnTemp.add(a.getAltitude());
                jsonObjectStart.put("position", jsnTemp);
                jsonArrayStart.add(jsonObjectStart);
            });
        }catch (Exception e){
           log.error("数据错误：{}",e.getMessage(),e);
        }
        return jsonArrayStart;
    }

    public static List<List<TrackPoint>> dataAreaInfo(String rectanglePoint, double safeDistance, List<TrackPoint> track) {
        List<Integer> tempMap = new ArrayList<>(1024);
        int row = track.size();
        for (int i = 0; i < row; i++) {
            TrackPoint trackPointInfo = track.get(i);
            if (trackPointInfo.isConflictPoint()) {
                //计算一个
                if(tempMap.size()==0) {
                    tempMap.add(i);
                }
            }
        }
        return  rectanglePointData(tempMap, track, safeDistance, rectanglePoint);
    }

    private static List<List<TrackPoint>> rectanglePointData(List<Integer> indexList, List<TrackPoint> track, double safeDistance, String rectanglePoint) {
        List<List<TrackPoint>> reList=new ArrayList<>();
        if (indexList.size() == 0) {
            return reList;
        }
        List<List<Integer>> listIndex = CurrentListGroup.groupConsecutiveNumbers(indexList);

        listIndex.forEach(a -> {
            //在区域内有冲突
            boolean flag = CurrentListGroup.isInRectangle(a, track, rectanglePoint);
            if (flag) {
                List<TrackPoint> list=  CurrentListGroup.newPointsInfo(a,track,safeDistance);
                if(!list.isEmpty()) {
                    reList.add(list);
                }
            }
        });
        return reList;
    }

    private static List<TrackPoint> newPointsInfo(List<Integer> indexList, List<TrackPoint> track, double safeDistance) {
        int row=indexList.size();
        int startIndex=indexList.get(0)-1;
        int endIndex=indexList.get(row-1)+2;

        List<TrackPoint> listOld =  new ArrayList(track.subList(startIndex,endIndex));

        StringBuffer sbOld=new StringBuffer();

        List<TrackPoint> pointVos= track.subList(startIndex,endIndex);
        List<Coordinate> points=new ArrayList<>();
        pointVos.forEach(a->{
            double lon = a.getPosition()[0];
            double lat =  a.getPosition()[1];
            Coordinate coordinate=new Coordinate(lon,lat);
            points.add(coordinate);
        });
        List<Point> pointsTemp=KeepPointDateInfo.dataInfo(points, (int) (safeDistance+10));

        for(int i=startIndex;i<endIndex;i++){
            Point coordinate = pointsTemp.get(i-startIndex);
            TrackPoint s=  track.get(i);
            double[] doubles=new double[2];
            doubles[0]=coordinate.coordinates().get(0);
            doubles[1]=coordinate.coordinates().get(1);
            s.setPosition(doubles);
        }

        track.forEach(a->{
            sbOld.append(a.getPosition()[0]);
            sbOld.append(",");
            sbOld.append(a.getPosition()[1]);
            sbOld.append(";");
        });
        sbOld.deleteCharAt(sbOld.length()-1);


        StringBuffer sb=new StringBuffer();
        listOld.forEach(a->{
            sb.append(a.getPosition()[0]);
            sb.append(",");
            sb.append(a.getPosition()[1]);
            sb.append(";");
        });

        sb.deleteCharAt(sb.length()-1);
        System.out.println("计算前--"+sb.toString());
        System.out.println("计算后--"+sbOld.toString());
        return listOld;
    }

}
